Hypothesis Tests on Audio Features
Two sample - independent tests
Independent here means that there is no reason to believe that
observations in the two samples can be paired in any way. (i.e. there’s
no reason to believe the danceability in the 60s is the same as the
2010s)
By randomly shuffling (i.e. permuting) the decade labels we lose any
relationship that there was between decade and danceability. Think of
this shuffling as detaching the labels from rows and then randomly
assigning them back to rows. Then we see which of the following
occurs:
If there was no relationship in the first place (i.e. they are in
fact independent) then randomly shuffling them should have no
implication. If the difference between groups in our sample is much
larger than the difference once the labels are shuffled it’s because
there is a real difference between the groups, and it’s not just down to
sampling variation.
This is an example of the hypothesis tests which were carried out on
each audio feature.
H0: The mean danceability in 1960s is the same as the mean
danceability in 2010s
Ha: The mean danceability in 1960s is less than the mean danceability
in 2010s
H0: The difference in means in 0 Ha: danceability2020 -
danceability1960 > 0
How do the audio features change over time
spotify_data_clean_pivot <- spotify_data_clean_join %>%
pivot_longer(cols = acousticness:valence,
names_to = "audio_feature",
values_to = "value") %>%
group_by(year, audio_feature) %>%
mutate(avg_feature = mean(value))
Plot with all Audio Features

Plot with audio features showing change

spotify_data_clean_join %>%
#mutate(explicit = as.numeric(explicit)) %>%
group_by(year) %>%
summarise(total_ex = sum(explicit)) %>%
ggplot() +
aes(x = year, y = total_ex / 20) +
geom_line(colour = "red", linewidth = 2) +
ylim(0, 50) +
labs(x = "Year",
y = "Proportion")+
# title = "Proportion of Explicit Songs",
# subtitle = "by year") +
theme_classic() +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 22, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 14, family = "Times"),
legend.title = element_blank()
)
ggsave("plot_images/explicit.png", dpi = 720, width = 10, height = 6)

spotify_data_clean_join %>%
group_by(year) %>%
summarise(mean_pop = mean(popularity)) %>%
ggplot() +
aes(x = year, y = mean_pop) +
geom_line(colour = "purple2", linewidth = 2) +
labs(x = "Year",
y = "Popularity") +
ylim(0, 100) +
theme_bw() +
scale_colour_brewer(palette = "Dark2") +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 22, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 14, family = "Times")
)
ggsave("plot_images/avg_pop.png", dpi = 720, width = 10, height = 6)

spot_sample %>%
ggplot() +
aes(x = danceability, y = popularity) +
geom_point(colour = "#1DB954", alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE, colour = "purple3", linewidth = 2) +
labs(x = "Danceability",
y = "Popularity") +
theme_classic() +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 20, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 14, family = "Times")
)

#ggsave("plot_images/pop_vs_dance.png", dpi = 720, width = 10, height = 6)
spot_sample %>%
ggplot() +
aes(x = loudness, y = popularity) +
geom_point(colour = "#1DB954", alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE, colour = "purple3", linewidth = 2) +
labs(x = "Loudness",
y = "Popularity") +
theme_classic() +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 22, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 14, family = "Times")
)
ggsave("plot_images/pop_vs_loud.png", dpi = 720, width = 10, height = 6)

Intro To Linear Regression
To help me answer my question of what makes a song “popular” on
spotify, I decided to build an explanatory linear regression model.
This type of analysis is used to determine the strength of the
relationship between a response variable and multiple explanatory
variables.
So in this case I will be choosing from all of the variables I have
just discussed to explain the popularity of a song on spotify.
y = b0 + b1x1 + b2x2 + b3x3….bnxn
popularity = b0 + b1x1 + b2x2 + b3x3….bnxn
To start this process I plot popularity against each one of my
variables or possible explanatory variables and find the strongest
correlation.
n_data <- nrow(spotify_data_for_modelling)
sample_index <- sample(1:n_data, size = n_data*0.1)
spot_sample <- slice(spotify_data_for_modelling, sample_index)
spot_sample %>%
ggplot() +
aes(x = year, y = popularity) +
geom_point(alpha = 0.7, colour = "#1DB954") +
geom_smooth(method = "lm", se = FALSE, colour = "purple2") +
theme_classic() +
labs(x = "Year",
y = "Popularity") +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 18, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 14, family = "Times")
)

#ggsave("plot_images/pop_vs_dance.png", dpi = 720, width = 10, height = 6)
spot_sample %>%
ggplot() +
aes(x = explicit, y = popularity) +
geom_point(alpha = 0.7, colour = "red4") +
geom_smooth(method = "lm", se = FALSE)

My strongest correlation was year (the year the track was released)
with a correlation of 0.74. I then add this to my model as my first
explanatory variable.
model_1a <- lm(popularity ~ year,
data = train_lm)
summary(model_1a)
Call:
lm(formula = popularity ~ year, data = train_lm)
Residuals:
Min 1Q Median 3Q Max
-19.600 -7.447 -1.773 5.668 54.400
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1220.936768 3.742482 -326.2 <0.0000000000000002 ***
year 0.634644 0.001881 337.4 <0.0000000000000002 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 10.08 on 95918 degrees of freedom
Multiple R-squared: 0.5427, Adjusted R-squared: 0.5427
F-statistic: 1.138e+05 on 1 and 95918 DF, p-value: < 0.00000000000000022
After running my model I’m looking at 3 factors: - The P-value - is
this variable making a significant difference. If the P-value is below
the significance level of 0.05 then we can reject the null hypothesis
and conclude that correlation between the variables is significant
- The R^2 - is a measure that indicates how much of the variation of
popularity is explained by the year
- The adjusted R^2 - compensates for the addition of variables. So as
we’re building an explanatory model, we don’t want this to drop much
lower than the r^2.
model_3a <- lm(popularity ~ year + danceability + loudness,
data = train_lm)
summary(model_3a)
model_3b <- lm(popularity ~ year + danceability + instrumentalness,
data = train_lm)
summary(model_3b)
anova(model_3a, model_2c)
Final Model
So here we have our final model. I stopped adding variables as the
Adjusted r^2 started dropping and our multiple r^2 was barely going
up.
So we can see that the more recent the release, the more
danceability, the louder it is, the less liveness it has. So you don’t
want a live recording, you want a studio recording with some explicit
lyrics chucked in there as well.
All of our P-Values are significant and we have a Multiple r^2 of
0.55, with an adjusted r^2 also of 0.55. This means that 55% of the
variance in popularity is explained our other variables. Which also
means that 45% of the variability in the data cannot be explained by
this model.
55% isn’t a very high proportion but it’s not terrible. We are trying
to measure the popularity of a song. It’s not quite as obvious as if we
were trying to explain the value of a house. We might find that the
postcode and the number of rooms goes a long way to explaining that
value. I think explaining the popularity of a song is bit more
complicated than that. If it was easy to know what made a song popular
then we’d all be musicians.
Mention human behaviour, mention the basic practice of statistics
would call this a moderate effect size.
So my model isn’t great. What can I do to improve this? Well…
When I was researching how spotify calculate their popularity score I
kept coming across this one phrase.
50 is the magic number
The higher your popularity index, the more likely the algorithm is to
recommend you to new listeners, and place you in algorithmic playlists
like Release Radar and Discover Weekly. Many websites and blogs had
theories on what number you had to hit to be added to certain editorial
playlists.
DIYMusician suggests that and popularity of 20+ in the first few
weeks of release will get you onto the Release Radar playlist and a
popularity score of 30+ will get you onto Discover Weekly. Loudlab
suggested that 50 is the magic number. I liked this idea of having a
threshold of whether or not a song is popular. So going back to my
variables I created a column called is_popular which is only TRUE if the
popularity of the song is 50 or over. This also lends itself nicely to a
logistic regression model.
Logistic regression is a statistical analysis method to predict, or
explain a binary outcome, such as yes or no, based on prior observations
of a data set.
So rather than using the popularity score I have used the variable I
created called is_popular, which splits the data in to a logical type,
so it’s TRUE if the song is 50 or above.
The way this is built is very similar to the linear model. I look for
correlations, and I add them to my model 1 at a time, check they are
significant. The main difference is that I’m looking for for a high AUC
score this time, rather than the multiple r^squared I was looking for in
the linear model.
I’ll explain the AUC in a second. I decided for this model to make a
couple of changes. I decided to no longer include the year or decade the
song was released. If I’m staying true to my original question then how
could I possibly write a song that was released in the past. It had such
a large influence on the linear model I thought it would be more
interesting to see how the logistic model fared without it. And then I
can test my model against different decades to see how it performs.
Oscar Wilde is famously credited with having written: “Popularity is
the one insult I have never suffered.”
spot_sample %>%
mutate(explicit = as.logical(explicit)) %>%
ggplot() +
aes(x = loudness, y = popularity, colour = explicit) +
geom_point(alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE) +
labs(x = "Loudness",
y = "Popularity",
title = "Relationship between Popularity and Loundess",
subtitle = "Grouped by explicit or not") +
scale_colour_brewer(palette = "Dark2") +
theme_bw() +
theme(axis.text = element_text(face = "bold", size = 15, family = "Times"),
axis.title = element_text(face = "bold", size = 15, family = "Times"),
title = element_text(face = "bold", size = 15, family = "Times"),
legend.text = element_text(face = "bold", size = 10, family = "Times")
)

spot_sample %>%
mutate(explicit = as.logical(explicit)) %>%
ggplot() +
aes(x = loudness, y = as.integer(is_popular), colour = explicit) +
geom_jitter(shape = 1,
position = position_jitter(h = 0.05, w = 0.05),
alpha = 0.8) +
geom_line(data = train_model_1_loud, aes(x = loudness , y = pred), col = 'red') +
ylab("Probability") +
scale_colour_brewer(palette = "Dark2") +
theme_bw() +
theme(axis.text = element_text(face = "bold", size = 15, family = "Times"),
axis.title = element_text(face = "bold", size = 15, family = "Times"),
title = element_text(face = "bold", size = 15, family = "Times"),
legend.text = element_text(face = "bold", size = 10, family = "Times")
)

# ggplot(mortgage_data) +
# geom_jitter(aes(x = tu_score, y = as.integer(accepted)), shape = 1,
# position = position_jitter(h = 0.03)) +
# geom_line(data = predict_log, aes(x = tu_score , y = pred), col = 'red') +
# ylab("Probability")
Final Logistic Regression Model
model_4_final <- glm(is_popular ~ loudness + explicit + danceability + no_of_artists,
family = "binomial",
data = train_log_mod)
summary(model_4_final)
Call:
glm(formula = is_popular ~ loudness + explicit + danceability +
no_of_artists, family = "binomial", data = train_log_mod)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.3012 -0.8550 -0.6624 1.1355 3.7138
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -7.7547047 0.0993408 -78.06 <0.0000000000000002 ***
loudness 0.0780446 0.0012231 63.81 <0.0000000000000002 ***
explicit 1.0409331 0.0237662 43.80 <0.0000000000000002 ***
danceability 0.0095757 0.0004548 21.06 <0.0000000000000002 ***
no_of_artists 0.1844060 0.0114087 16.16 <0.0000000000000002 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 121164 on 97324 degrees of freedom
Residual deviance: 110272 on 97320 degrees of freedom
AIC: 110282
Number of Fisher Scoring iterations: 4
tidy(model_4_final)
train_model_4_final <- train_log_mod %>%
add_predictions(model_4_final, type = "response")
roc_obj_mod4 <- train_model_4_final %>%
roc(response = is_popular, predictor = pred)
Setting levels: control = FALSE, case = TRUE
Setting direction: controls < cases
roc_curve <- ggroc(
data = list(
best_model = roc_obj_mod4
),
legacy.axes = TRUE) +
coord_fixed() +
theme_classic()
auc(roc_obj_mod4)
Area under the curve: 0.7223
log_mod_1990 <- train_log_mod %>%
filter(decade == 1990 |
decade == 2000 |
decade == 2010)
model_90_00_10 <- glm(is_popular ~ loudness + explicit + danceability + no_of_artists,
family = "binomial",
data = log_mod_1990)
summary(model_90_00_10)
Call:
glm(formula = is_popular ~ loudness + explicit + danceability +
no_of_artists, family = "binomial", data = log_mod_1990)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.2496 -1.1659 0.8386 1.1431 2.3491
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.1595029 0.1137598 -27.773 < 0.0000000000000002 ***
loudness 0.0342887 0.0014178 24.185 < 0.0000000000000002 ***
explicit 0.4662174 0.0258787 18.016 < 0.0000000000000002 ***
danceability 0.0031530 0.0005672 5.559 0.0000000271 ***
no_of_artists 0.1691662 0.0143345 11.801 < 0.0000000000000002 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 66344 on 47879 degrees of freedom
Residual deviance: 64758 on 47875 degrees of freedom
AIC: 64768
Number of Fisher Scoring iterations: 4
tidy(model_90_00_10)
train_model_90_00_10 <- log_mod_1990 %>%
add_predictions(model_90_00_10, type = "response")
roc_obj_mod_90_00_10 <- train_model_90_00_10 %>%
roc(response = is_popular, predictor = pred)
Setting levels: control = FALSE, case = TRUE
Setting direction: controls < cases
roc_curve <- ggroc(
data = list(
best_model = roc_obj_mod4,
dec_60s_70s_80s = roc_obj_mod_60_70_80,
dec_90s_00s_10s = roc_obj_mod_90_00_10
),
legacy.axes = TRUE,
linewidth = 2) +
coord_fixed() +
labs(x = "1 - Specificity",
y = "Sensitivity") +
scale_colour_brewer(palette = "Dark2") +
scale_colour_discrete(labels = c("Final Model", "60s, 70s & 80s", "90s, 00s & 10s")) +
theme_classic() +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 18, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 18, family = "Times"),
#legend.text = element_blank(),
legend.title = element_blank()
#legend.key = element_blank()
)
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
auc(roc_obj_mod_90_00_10)
Area under the curve: 0.629
roc_curve
ggsave("plot_images/log_models.png", dpi = 720, width = 12, height = 6)

log_mod_1990 <- train_log_mod %>%
filter(decade == 1990 |
decade == 2000 |
decade == 2010)
model_90_00_10 <- glm(is_popular ~ loudness + explicit + danceability + no_of_artists,
family = "binomial",
data = log_mod_1990)
summary(model_90_00_10)
Call:
glm(formula = is_popular ~ loudness + explicit + danceability +
no_of_artists, family = "binomial", data = log_mod_1990)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.2496 -1.1659 0.8386 1.1431 2.3491
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.1595029 0.1137598 -27.773 < 0.0000000000000002 ***
loudness 0.0342887 0.0014178 24.185 < 0.0000000000000002 ***
explicit 0.4662174 0.0258787 18.016 < 0.0000000000000002 ***
danceability 0.0031530 0.0005672 5.559 0.0000000271 ***
no_of_artists 0.1691662 0.0143345 11.801 < 0.0000000000000002 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 66344 on 47879 degrees of freedom
Residual deviance: 64758 on 47875 degrees of freedom
AIC: 64768
Number of Fisher Scoring iterations: 4
tidy(model_90_00_10)
train_model_90_00_10 <- log_mod_1990 %>%
add_predictions(model_90_00_10, type = "response")
roc_obj_mod_90_00_10 <- train_model_90_00_10 %>%
roc(response = is_popular, predictor = pred)
Setting levels: control = FALSE, case = TRUE
Setting direction: controls < cases
roc_curve <- ggroc(
data = list(
best_model = roc_obj_mod4
),
legacy.axes = TRUE,
linewidth = 2) +
coord_fixed() +
labs(x = "1 - Specificity",
y = "Sensitivity") +
scale_colour_brewer(palette = "Dark2") +
scale_colour_discrete(labels = "Final Model") +
theme_classic() +
theme(axis.text = element_text(face = "bold", size = 18, family = "Times"),
axis.title = element_text(face = "bold", size = 18, family = "Times"),
title = element_text(face = "bold", size = 18, family = "Times"),
legend.text = element_text(face = "bold", size = 16, family = "Times"),
legend.title = element_blank()
)
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
auc(roc_obj_mod_90_00_10)
Area under the curve: 0.629
roc_curve
ggsave("plot_images/log_best_model.png", dpi = 720, width = 12, height = 6)

LS0tCnRpdGxlOiAiU3BvdGlmeSBBbmFseXNpcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShzcG90aWZ5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobW9kZWxyKQpsaWJyYXJ5KGluZmVyKQpsaWJyYXJ5KG1vZGVscikKbGlicmFyeShnZ2ZvcnRpZnkpCmxpYnJhcnkoR0dhbGx5KQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CnNwb3RpZnlfZGF0YV9jbGVhbl9qb2luIDwtIHJlYWRfY3N2KCJjbGVhbl9kYXRhL3Nwb3RpZnlfY2xlYW5fam9pbi5jc3YiKQpzcG90aWZ5X2RhdGEgPC0gcmVhZF9jc3YoInJhd19kYXRhL3Nwb3RpZnlfZGF0YS5jc3YiKQpgYGAKCgojIyMgUXVlc3Rpb24KCldoYXQgKGF1ZGlvIGZlYXR1cmVzKSBtYWtlcyBhIHNvbmcgcG9wdWxhciwgYW5kIGhhcyB0aGF0IGNoYW5nZWQgb3ZlciB0aW1lPwoKIyMjIEludHJvCgpJIGhhdmUgYmVlbiB0YXNrZWQgYnkgbXkgY2xpZW50LCBVbml2ZXJzYWwgUmVjb3JkcyB0byBpbnZlc3RpZ2F0ZSB3aGF0IG1ha2VzIGEgc29uZyBwb3B1bGFyIG9uIHNwb3RpZnkgaW4gb3JkZXIgdG8gaW5mb3JtIGZ1dHVyZSByZWxlYXNlcy4gCgpGb3IgdGhpcyBwcm9qZWN0IEkgaGF2ZSB1c2VkIGEgY29tYmluYXRpb24gb2YgU3BvdGlmeSBkYXRhc2V0cyBhdmFpbGFibGUgb24gS2FnZ2xlLCB0YWtlbiBmcm9tIHRoZSBTcG90aWZ5IFdlYiBBUEkuIFRoZSBvcmlnaW5hbCBkYXRhc2V0IGNvbnRhaW5zIGp1c3QgdW5kZXIgMTcwLDAwMCByb3dzIHdpdGggMTkgY29sdW1ucy4gSSBoYXZlIHRoZW4gam9pbmVkIHRoaXMgd2l0aCBhbm90aGVyIGRhdGFzZXQgd2hpY2ggZ2F2ZSBtZSBpbmZvcm1hdGlvbiBvbiAiZ2VucmVzIiBhbmQgImZvbGxvd2VycyIuIChhbmQgdGltZSBzaWduYXR1cmUpIEVhY2ggcm93IGluIHRoZSBkYXRhc2V0IHJlcHJlc2VudHMgMSBzb25nLCBpbmZvcm1hdGlvbiBhYm91dCB0aGF0IHNvbmcgYW5kIG1hbnkgb2YgaXQncyBhdWRpbyBmZWF0dXJlcy4KCkkgaGF2ZSB1c2VkIFJTdHVkaW8gZm9yIHRoaXMgcHJvamVjdCBhcyBJIGZvdW5kIGl0IGV4Y2VsbGVudCBmb3IgbW9kZWwgYnVpbGRpbmcuCgpJIGhhZCBubyBpc3N1ZXMgc3Vycm91bmRpbmcgdGhlIGV0aGljcyBvZiB1c2luZyBvciBwcmVzZW50aW5nIHRoaXMgZGF0YS4gSSBoYWQgdG8gZ2V0IGF1dGhlbnRpY2F0aW9uIHRvIHVzZSB0aGUgU3BvdGlmeSB3ZWIgYXBpIGJ1dCBpdCBpcyByZWFkaWx5IGF2YWlsYWJsZSBmb3IgcGVvcGxlIHRvIHZpZXcgYW5kIGFuYWx5c2UuCgojIyMgVGhlIFZhcmlhYmxlcwoKQmFzaWMgSW5mbwphcnRpc3RzIDxjaHI+IC0gdGhlIGFydGlzdCBvciBhcnRpc3RzIHdobyBhcHBlYXJzIG9uIHRoZSB0cmFjawp0cmFja19uYW1lIDxjaHI+IC0gbmFtZSBvZiB0aGUgc29uZwp0cmFja19pZCA8Y2hyPiAtIGEgZGlzdGluY3QgaWQgdG8gcmVwcmVzZW50IHRoZSBzb25nCnllYXIgPGRhdGU+IC0geWVhciB0aGUgdHJhY2sgd2FzIHJlbGVhc2VkCmR1cmF0aW9uX3NlYyA8ZGJsPiAtIGR1cmF0aW9uIG9mIHRoZSB0cmFjayBpbiBzZWNvbmRzCmtleSA8ZmN0cj4gLSB0aGUga2V5IG9mIHRoZSBzb25nICAwLTExCm1vZGUgPGZjdHI+IC0gbWFqb3Igb3IgbWlub3Iga2V5CnRpbWVfc2lnbmF0dXJlIDxmY3RyPiAtIHRpbWUgc2lnbmF0dXJlIG9mIHRoZSBzb25nCnRlbXBvIDxkYmw+IC0gb3ZlcmFsbCB0ZW1wbyBvZiB0aGUgdHJhY2sgaW4gQlBNCmV4cGxpY2l0IDxmY3Q+IC0gZG9lcyB0aGUgdHJhY2sgY29udGFpbiBleHBsaWNpdCBjb250ZW50CgpkZWNhZGUgPGRhdGU+IC0gZGVjYWRlIG9mIHJlbGVhc2UKbm9fb2ZfYXJ0aXN0cyA8ZGJsPiAtIHRoZSBudW1iZXIgb2YgYXJ0aXN0cyBhcHBlYXJpbmcgb24gZWFjaCB0cmFjawpmb2xsb3dlcnMgLSAKZ2VucmUgLSAKaXNfcG9wdWxhciA8bGdsPiAtIGlzIHRoZSBwb3B1bGFyaXR5IHJhdGluZyA1MCBvciBvdmVyCgoKQWxsIG9uIGEgc2NhbGUgb2YgMCAtIDEwMAogLSBhY291c3RpY25lc3MgPGRibD4gLSBhIG1lYXN1cmUgb2YgaG93IGFjb3VzdGljIHRoZSB0cmFjayBpcyAod2FzIGl0IHJlY29yZGVkIGluIGEgbGl2ZSBzZXR0aW5nIG9yIHN0dWRpbykKCiAtIGRhbmNlYWJpbGl0eSA8ZGJsPiAtIGhvdyBzdWl0YWJsZSBpcyB0aGUgdHJhY2sgZm9yIGRhbmNpbmcsIGJhc2VkIG9uIHJoeXRobSBzdGFiaWxpdHksIHRlbXBvIGFuZCBiZWF0IHN0cmVuZ3RoLgoKLSBlbmVyZ3kgLSBtZWFzdXJlcyB0aGUgaW50ZW5zaXR5IGFuZCBhY3Rpdml0eSBsZXZlbAoKLSBpbnN0cnVtZW50YWxuZXNzIC0gbWVhc3VyZXMgaG93IG11Y2ggdm9jYWxzIHRoZXJlIGFyZSBpbiBhIHRyYWNrLiBUaGUgaGlnaGVyIHRoZSBudW1iZXIsIHRoZSBsZXNzIHZvY2FscyBpbiB0aGUgdHJhY2sKCi0gbGl2ZW5lc3MgLSBkZXRlY3RzIHRoZSBwcmVzZW5jZSBvZiBhbiBhdWRpZW5jZSBpbiB0aGUgcmVjb3JkaW5nLiBUaGUgaGlnaGVyIHRoZSBsaXZlbmVzcyB0aGUgaGlnaGVyIHRoZSBwcm9iYWJpbGl0eSBpdCB3YXMgcmVjb3JkZWQgbGl2ZS4KCi0gbG91ZG5lc3MgLSB0aGUgb3ZlcmFsbCBsb3VkbmVzcyBvZiBhIHRyYWNrLiBPcmlnaW5hbGx5IGluIGRiLCBzY2FsZWQgdG8gbWF0Y2ggdGhlIG90aGVyIGF1ZGlvIGZlYXR1cmVzLgoKLSBzcGVlY2hpbmVzcyAtIG1lYXN1cmVzIHRoZSBwcmVzZW5jZSBvZiBzcG9rZW4gd29yZCBpbiBhIHRyYWNrLiBUaGUgY2xvc2VyIHRvIDEwMCwgdGhlIG1vcmUgZXhjbHVzaXZlbHkgc3BlZWNoLWxpa2UgdGhlIHJlY29yZGluZy4gUmFwIGhhcyBoaWdoZXIgc2NvcmUgdGhhbiBmb2xrLgoKLSB2YWxlbmNlIC0gdGhlIGhpZ2hlciB0aGUgdmFsdWUgdGhlIG1vcmUgcG9zaXRpdmUgYSB0cmFjayBzb3VuZHMoZS5nLiBoYXBweSwgY2hlZXJmdWwpLiBUaGUgbG93ZXIgdGhlIHNjb3JlIHRoZSBtb3JlIG5lZ2F0aXZlIGl0IHNvdW5kcyAoZS5nLiBzYWQsIGFuZ3J5KQoKIyMjIHBvcHVsYXJpdHkgLSAgU3BvdGlmeSAtICAiVGhlIHBvcHVsYXJpdHkgb2YgYSB0cmFjayBpcyBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMTAwLCB3aXRoIDEwMCBiZWluZyB0aGUgbW9zdCBwb3B1bGFyLiBUaGUgcG9wdWxhcml0eSBpcyBjYWxjdWxhdGVkIGJ5IGFsZ29yaXRobSBhbmQgaXMgYmFzZWQsIGluIHRoZSBtb3N0IHBhcnQsIG9uIHRoZSB0b3RhbCBudW1iZXIgb2YgcGxheXMgdGhlIHRyYWNrIGhhcyBoYWQgYW5kIGhvdyByZWNlbnQgdGhvc2UgcGxheXMgYXJlLiIKCgojIyBIeXBvdGhlc2lzIFRlc3RzIG9uIEF1ZGlvIEZlYXR1cmVzCgpUd28gc2FtcGxlIC0gaW5kZXBlbmRlbnQgdGVzdHMKCkluZGVwZW5kZW50IGhlcmUgbWVhbnMgdGhhdCB0aGVyZSBpcyBubyByZWFzb24gdG8gYmVsaWV2ZSB0aGF0IG9ic2VydmF0aW9ucyBpbiB0aGUgdHdvIHNhbXBsZXMgY2FuIGJlIHBhaXJlZCBpbiBhbnkgd2F5LiAoaS5lLiB0aGVyZSdzIG5vIHJlYXNvbiB0byBiZWxpZXZlIHRoZSBkYW5jZWFiaWxpdHkgaW4gdGhlIDYwcyBpcyB0aGUgc2FtZSBhcyB0aGUgMjAxMHMpCgpCeSByYW5kb21seSBzaHVmZmxpbmcgKGkuZS4gcGVybXV0aW5nKSB0aGUgZGVjYWRlIGxhYmVscyB3ZSBsb3NlIGFueSByZWxhdGlvbnNoaXAgdGhhdCB0aGVyZSB3YXMgYmV0d2VlbiBkZWNhZGUgYW5kIGRhbmNlYWJpbGl0eS4gVGhpbmsgb2YgdGhpcyBzaHVmZmxpbmcgYXMgZGV0YWNoaW5nIHRoZSBsYWJlbHMgZnJvbSByb3dzIGFuZCB0aGVuIHJhbmRvbWx5IGFzc2lnbmluZyB0aGVtIGJhY2sgdG8gcm93cy4gVGhlbiB3ZSBzZWUgd2hpY2ggb2YgdGhlIGZvbGxvd2luZyBvY2N1cnM6CgpJZiB0aGVyZSB3YXMgbm8gcmVsYXRpb25zaGlwIGluIHRoZSBmaXJzdCBwbGFjZSAoaS5lLiB0aGV5IGFyZSBpbiBmYWN0IGluZGVwZW5kZW50KSB0aGVuIHJhbmRvbWx5IHNodWZmbGluZyB0aGVtIHNob3VsZCBoYXZlIG5vIGltcGxpY2F0aW9uLgpJZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGdyb3VwcyBpbiBvdXIgc2FtcGxlIGlzIG11Y2ggbGFyZ2VyIHRoYW4gdGhlIGRpZmZlcmVuY2Ugb25jZSB0aGUgbGFiZWxzIGFyZSBzaHVmZmxlZCBpdOKAmXMgYmVjYXVzZSB0aGVyZSBpcyBhIHJlYWwgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBncm91cHMsIGFuZCBpdOKAmXMgbm90IGp1c3QgZG93biB0byBzYW1wbGluZyB2YXJpYXRpb24uCgpUaGlzIGlzIGFuIGV4YW1wbGUgb2YgdGhlIGh5cG90aGVzaXMgdGVzdHMgd2hpY2ggd2VyZSBjYXJyaWVkIG91dCBvbiBlYWNoIGF1ZGlvIGZlYXR1cmUuCgpIMDogVGhlIG1lYW4gZGFuY2VhYmlsaXR5IGluIDE5NjBzIGlzIHRoZSBzYW1lIGFzIHRoZSBtZWFuIGRhbmNlYWJpbGl0eSBpbiAyMDEwcwoKSGE6IFRoZSBtZWFuIGRhbmNlYWJpbGl0eSBpbiAxOTYwcyBpcyBsZXNzIHRoYW4gdGhlIG1lYW4gZGFuY2VhYmlsaXR5IGluIDIwMTBzCgpIMDogVGhlIGRpZmZlcmVuY2UgaW4gbWVhbnMgaW4gMApIYTogZGFuY2VhYmlsaXR5MjAyMCAtIGRhbmNlYWJpbGl0eTE5NjAgPiAwCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRhbmNlX2RlY2FkZV9oeXAgPC0gc3BvdGlmeV9kYXRhX2NsZWFuX2pvaW4gJT4lIAogIHNlbGVjdChkZWNhZGUsIGRhbmNlYWJpbGl0eSkgJT4lIAogIGZpbHRlcihkZWNhZGUgPT0gMTk2MCB8IGRlY2FkZSA9PSAyMDEwKSAlPiUgCiAgbXV0YXRlKGRlY2FkZSA9IGFzLmZhY3RvcihkZWNhZGUpKQoKbnVsbF9kaXN0cmlidXRpb24gPC0gZGFuY2VfZGVjYWRlX2h5cCAlPiUgCiAgc3BlY2lmeShkYW5jZWFiaWxpdHkgfiBkZWNhZGUpICU+JSAKICBoeXBvdGhlc2l6ZShudWxsID0gImluZGVwZW5kZW5jZSIpICU+JSAKICBnZW5lcmF0ZShyZXBzID0gNTAwMCwgdHlwZSA9ICJwZXJtdXRlIikgJT4lIAogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoIjIwMTAiLCAiMTk2MCIpKSAKCm9ic2VydmVkX3N0YXQgPC0gZGFuY2VfZGVjYWRlX2h5cCAlPiUgCiAgc3BlY2lmeShkYW5jZWFiaWxpdHkgfiBkZWNhZGUpICU+JQogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoIjIwMTAiLCAiMTk2MCIpKQoKbnVsbF9kaXN0cmlidXRpb24gJT4lCiAgdmlzdWFsaXNlKCkgKwogIHNoYWRlX3BfdmFsdWUob2JzX3N0YXQgPSBvYnNlcnZlZF9zdGF0LCBkaXJlY3Rpb24gPSAicmlnaHQiKQoKcF92YWx1ZSA8LSBudWxsX2Rpc3RyaWJ1dGlvbiAlPiUKICBnZXRfcF92YWx1ZShvYnNfc3RhdCA9IG9ic2VydmVkX3N0YXQsIGRpcmVjdGlvbiA9ICJyaWdodCIpCmBgYAoKIyMjIEhvdyBkbyB0aGUgYXVkaW8gZmVhdHVyZXMgY2hhbmdlIG92ZXIgdGltZQoKYGBge3J9CnNwb3RpZnlfZGF0YV9jbGVhbl9waXZvdCA8LSBzcG90aWZ5X2RhdGFfY2xlYW5fam9pbiAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBhY291c3RpY25lc3M6dmFsZW5jZSwKICAgICAgICAgICAgICBuYW1lc190byA9ICJhdWRpb19mZWF0dXJlIiwKICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUgCiAgZ3JvdXBfYnkoeWVhciwgYXVkaW9fZmVhdHVyZSkgJT4lIAogIG11dGF0ZShhdmdfZmVhdHVyZSA9IG1lYW4odmFsdWUpKQpgYGAKCgpQbG90IHdpdGggYWxsIEF1ZGlvIEZlYXR1cmVzCmBgYHtyfQphdWRpb3RfZmVhdHVyZXNfYWxsIDwtIHNwb3RpZnlfZGF0YV9jbGVhbl9waXZvdCAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSB5ZWFyLCB5ID0gYXZnX2ZlYXR1cmUsIGdyb3VwID0gYXVkaW9fZmVhdHVyZSwgCiAgICAgIGNvbG91ciA9IGF1ZGlvX2ZlYXR1cmUpICsKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKwogIHlsaW0oMCwgMTAwKSArCiAgbGFicyh4ID0gIlllYXIiLAogICAgICAgeSA9ICJWYWx1ZSIsCiAgICAgICB0aXRsZSA9ICJBdWRpbyBGZWF0dXJlcyBPdmVyIFRpbWUiLAogICAgICAgc3VidGl0bGUgPSAiQXZnIHBlciB5ZWFyIiwKICAgICAgIGNvbG91ciA9ICJBdWRpbyBGZWF0dXJlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICAiRGFyazIiKSArCiAgdGhlbWUoYXhpcy50ZXh0ICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGF4aXMudGl0bGUgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTQsIGZhbWlseSA9ICJUaW1lcyIpCiAgKSAKCiNnZ3NhdmUoYXVkaW90X2ZlYXR1cmVzX2FsbCwgInBsb3RfaW1hZ2VzL2F1ZGlvX2ZlYXR1cmVzX2FsbC5wbmciKQpgYGAKClBsb3Qgd2l0aCBhdWRpbyBmZWF0dXJlcyBzaG93aW5nIGNoYW5nZQpgYGB7cn0KYXVkaW9fZmVhdHVyZXNfY3V0IDwtIHNwb3RpZnlfZGF0YV9jbGVhbl9waXZvdCAlPiUKICAgIGZpbHRlcihhdWRpb19mZWF0dXJlID09ICJhY291c3RpY25lc3MiIHwKICAgICAgICAgICBhdWRpb19mZWF0dXJlID09ICJpbnN0cnVtZW50YWxuZXNzIiB8CiAgICAgICAgICAgYXVkaW9fZmVhdHVyZSA9PSAiZGFuY2VhYmlsaXR5IiB8CiAgICAgICAgICAgYXVkaW9fZmVhdHVyZSA9PSAic3BlZWNoaW5lc3MiIHwKICAgICAgICAgICBhdWRpb19mZWF0dXJlID09ICJsb3VkbmVzcyIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSB5ZWFyLCB5ID0gYXZnX2ZlYXR1cmUsIGdyb3VwID0gYXVkaW9fZmVhdHVyZSwgCiAgICAgIGNvbG91ciA9IGF1ZGlvX2ZlYXR1cmUpICsKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKwogIHlsaW0oMCwgMTAwKSArCiAgbGFicyh4ID0gIlllYXIiLAogICAgICAgeSA9ICJWYWx1ZSIsCiAgICAgICAjIHRpdGxlID0gIkF1ZGlvIEZlYXR1cmVzIGJ5IFJlbGVhc2UgWWVhciIsCiAgICAgICAjIHN1YnRpdGxlID0gIkF2ZyBwZXIgeWVhciIsCiAgICAgICBjb2xvdXIgPSAiQXVkaW8gRmVhdHVyZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAgIkRhcmsyIikgKwogIHNjYWxlX2NvbG91cl9kaXNjcmV0ZShsYWJlbHMgPSBjKCJBY291c3RpY25lc3MiLCAiRGFuY2VhYmlsaXR5IiwgIkluc3RydW1lbnRhbG5lc3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMb3VkbmVzcyIsICJTcGVlY2hpbmVzcyIpKSArCgogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDIwLCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMjIsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDIwLCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICApIAoKZ2dzYXZlKCJwbG90X2ltYWdlcy9hdWRpb19mZWF0dXJlc19jdXQucG5nIiwgZHBpID0gNzIwLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA2KQoKP2dnc2F2ZQpgYGAKCmBgYHtyfQpzcG90aWZ5X2RhdGFfY2xlYW5fam9pbiAlPiUgCiAgI211dGF0ZShleHBsaWNpdCA9IGFzLm51bWVyaWMoZXhwbGljaXQpKSAlPiUgCiAgZ3JvdXBfYnkoeWVhcikgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF9leCA9IHN1bShleHBsaWNpdCkpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSB5ZWFyLCB5ID0gdG90YWxfZXggLyAyMCkgKwogIGdlb21fbGluZShjb2xvdXIgPSAicmVkIiwgbGluZXdpZHRoID0gMikgKwogIHlsaW0oMCwgNTApICsKICBsYWJzKHggPSAiWWVhciIsCiAgICAgICB5ID0gIlByb3BvcnRpb24iKSsKICAgICAgICMgdGl0bGUgPSAiUHJvcG9ydGlvbiBvZiBFeHBsaWNpdCBTb25ncyIsCiAgICAgICAjIHN1YnRpdGxlID0gImJ5IHllYXIiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDIyLCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgZmFtaWx5ID0gIlRpbWVzIikKICApIAoKZ2dzYXZlKCJwbG90X2ltYWdlcy9leHBsaWNpdC5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCmBgYApgYGB7cn0Kc3BvdGlmeV9kYXRhX2NsZWFuX2pvaW4gJT4lIAogIGdyb3VwX2J5KHllYXIpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wb3AgPSBtZWFuKHBvcHVsYXJpdHkpKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0geWVhciwgeSA9IG1lYW5fcG9wKSArCiAgZ2VvbV9saW5lKGNvbG91ciA9ICJwdXJwbGUyIiwgbGluZXdpZHRoID0gMikgKwogIGxhYnMoeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiUG9wdWxhcml0eSIpICsKICB5bGltKDAsIDEwMCkgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICAiRGFyazIiKSArCiAgdGhlbWUoYXhpcy50ZXh0ICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGF4aXMudGl0bGUgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAyMiwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTQsIGZhbWlseSA9ICJUaW1lcyIpCiAgKSAKCmdnc2F2ZSgicGxvdF9pbWFnZXMvYXZnX3BvcC5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCgpgYGAKCmBgYHtyfQpzcG90X3NhbXBsZSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gZGFuY2VhYmlsaXR5LCB5ID0gcG9wdWxhcml0eSkgKwogIGdlb21fcG9pbnQoY29sb3VyID0gIiMxREI5NTQiLCBhbHBoYSA9IDAuOCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGNvbG91ciA9ICJwdXJwbGUzIiwgbGluZXdpZHRoID0gMikgKwogIGxhYnMoeCA9ICJEYW5jZWFiaWxpdHkiLAogICAgICAgeSA9ICJQb3B1bGFyaXR5IikgKwogICAgICAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDIwLCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgZmFtaWx5ID0gIlRpbWVzIikKICApCgojZ2dzYXZlKCJwbG90X2ltYWdlcy9wb3BfdnNfZGFuY2UucG5nIiwgZHBpID0gNzIwLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQoKYGBgCgpgYGB7cn0Kc3BvdF9zYW1wbGUgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IGxvdWRuZXNzLCB5ID0gcG9wdWxhcml0eSkgKwogIGdlb21fcG9pbnQoY29sb3VyID0gIiMxREI5NTQiLCBhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGNvbG91ciA9ICJwdXJwbGUzIiwgbGluZXdpZHRoID0gMikgKwogIGxhYnMoeCA9ICJMb3VkbmVzcyIsCiAgICAgICB5ID0gIlBvcHVsYXJpdHkiKSArCiAgICAgICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMjIsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0LCBmYW1pbHkgPSAiVGltZXMiKQogICkKCmdnc2F2ZSgicGxvdF9pbWFnZXMvcG9wX3ZzX2xvdWQucG5nIiwgZHBpID0gNzIwLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQoKYGBgCgojIyMgSW50cm8gVG8gTGluZWFyIFJlZ3Jlc3Npb24KClRvIGhlbHAgbWUgYW5zd2VyIG15IHF1ZXN0aW9uIG9mIHdoYXQgbWFrZXMgYSBzb25nICJwb3B1bGFyIiBvbiBzcG90aWZ5LCBJIGRlY2lkZWQgdG8gYnVpbGQgYW4gZXhwbGFuYXRvcnkgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwuIAoKVGhpcyB0eXBlIG9mIGFuYWx5c2lzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBzdHJlbmd0aCBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYSByZXNwb25zZSB2YXJpYWJsZSBhbmQgbXVsdGlwbGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzLgoKU28gaW4gdGhpcyBjYXNlIEkgd2lsbCBiZSBjaG9vc2luZyBmcm9tIGFsbCBvZiB0aGUgdmFyaWFibGVzIEkgaGF2ZSBqdXN0IGRpc2N1c3NlZCB0byBleHBsYWluIHRoZSBwb3B1bGFyaXR5IG9mIGEgc29uZyBvbiBzcG90aWZ5LgoKeSA9IGIwICsgYjF4MSArIGIyeDIgKyBiM3gzLi4uLmJueG4KCnBvcHVsYXJpdHkgPSBiMCArIGIxeDEgKyBiMngyICsgYjN4My4uLi5ibnhuCgpUbyBzdGFydCB0aGlzIHByb2Nlc3MgSSBwbG90IHBvcHVsYXJpdHkgYWdhaW5zdCBlYWNoIG9uZSBvZiBteSB2YXJpYWJsZXMgb3IgcG9zc2libGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGFuZCBmaW5kIHRoZSBzdHJvbmdlc3QgY29ycmVsYXRpb24uCgpgYGB7cn0Kbl9kYXRhIDwtIG5yb3coc3BvdGlmeV9kYXRhX2Zvcl9tb2RlbGxpbmcpCgpzYW1wbGVfaW5kZXggPC0gc2FtcGxlKDE6bl9kYXRhLCBzaXplID0gbl9kYXRhKjAuMSkKCnNwb3Rfc2FtcGxlIDwtIHNsaWNlKHNwb3RpZnlfZGF0YV9mb3JfbW9kZWxsaW5nLCBzYW1wbGVfaW5kZXgpCgpzcG90X3NhbXBsZSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0geWVhciwgeSA9IHBvcHVsYXJpdHkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC43LCBjb2xvdXIgPSAiIzFEQjk1NCIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2xvdXIgPSAicHVycGxlMiIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGxhYnMoeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiUG9wdWxhcml0eSIpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgZmFtaWx5ID0gIlRpbWVzIikKICApCgojZ2dzYXZlKCJwbG90X2ltYWdlcy9wb3BfdnNfZGFuY2UucG5nIiwgZHBpID0gNzIwLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQpgYGAKCmBgYHtyfQpzcG90X3NhbXBsZSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gZXhwbGljaXQsIHkgPSBwb3B1bGFyaXR5KSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgY29sb3VyID0gInJlZDQiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkKYGBgCgoKTXkgc3Ryb25nZXN0IGNvcnJlbGF0aW9uIHdhcyB5ZWFyICh0aGUgeWVhciB0aGUgdHJhY2sgd2FzIHJlbGVhc2VkKSB3aXRoIGEgY29ycmVsYXRpb24gb2YgMC43NC4gSSB0aGVuIGFkZCB0aGlzIHRvIG15IG1vZGVsIGFzIG15IGZpcnN0IGV4cGxhbmF0b3J5IHZhcmlhYmxlLgoKYGBge3J9Cm1vZGVsXzFhIDwtIGxtKHBvcHVsYXJpdHkgfiB5ZWFyLAogICAgICAgICAgICAgICBkYXRhID0gdHJhaW5fbG0pCgpzdW1tYXJ5KG1vZGVsXzFhKQpgYGAKCkFmdGVyIHJ1bm5pbmcgbXkgbW9kZWwgSSdtIGxvb2tpbmcgYXQgMyBmYWN0b3JzOgogLSBUaGUgUC12YWx1ZSAtIGlzIHRoaXMgdmFyaWFibGUgbWFraW5nIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZS4gSWYgdGhlIFAtdmFsdWUgaXMgYmVsb3cgdGhlIHNpZ25pZmljYW5jZSBsZXZlbCBvZiAwLjA1IHRoZW4gd2UgY2FuIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIGFuZCBjb25jbHVkZSB0aGF0IGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHZhcmlhYmxlcyBpcyBzaWduaWZpY2FudAogCiAtIFRoZSBSXjIgLSBpcyBhIG1lYXN1cmUgdGhhdCBpbmRpY2F0ZXMgaG93IG11Y2ggb2YgdGhlIHZhcmlhdGlvbiBvZiBwb3B1bGFyaXR5IGlzIGV4cGxhaW5lZCBieSB0aGUgeWVhcgogLSBUaGUgYWRqdXN0ZWQgUl4yIC0gY29tcGVuc2F0ZXMgZm9yIHRoZSBhZGRpdGlvbiBvZiB2YXJpYWJsZXMuIFNvIGFzIHdlJ3JlIGJ1aWxkaW5nIGFuIGV4cGxhbmF0b3J5IG1vZGVsLCB3ZSBkb24ndCB3YW50IHRoaXMgdG8gZHJvcCBtdWNoIGxvd2VyIHRoYW4gdGhlIHJeMi4KCmBgYHtyfQptb2RlbF8zYSA8LSBsbShwb3B1bGFyaXR5IH4geWVhciArIGRhbmNlYWJpbGl0eSArIGxvdWRuZXNzLAogICAgICAgICAgICAgICBkYXRhID0gdHJhaW5fbG0pCgpzdW1tYXJ5KG1vZGVsXzNhKQpgYGAKCmBgYHtyfQptb2RlbF8zYiA8LSBsbShwb3B1bGFyaXR5IH4geWVhciArIGRhbmNlYWJpbGl0eSArIGluc3RydW1lbnRhbG5lc3MsCiAgICAgICAgICAgICAgIGRhdGEgPSB0cmFpbl9sbSkKCnN1bW1hcnkobW9kZWxfM2IpCmBgYAoKYGBge3J9CmFub3ZhKG1vZGVsXzNhLCBtb2RlbF8yYykKYGBgCgpGaW5hbCBNb2RlbAoKYGBge3J9Cm1vZGVsXzZhIDwtIGxtKHBvcHVsYXJpdHkgfiB5ZWFyICsgZGFuY2VhYmlsaXR5ICsgbG91ZG5lc3MgKyBsaXZlbmVzcyArIGV4cGxpY2l0LAogICAgICAgICAgICAgICBkYXRhID0gdHJhaW5fbG0pCgpzdW1tYXJ5KG1vZGVsXzZhKQpgYGAgCgpTbyBoZXJlIHdlIGhhdmUgb3VyIGZpbmFsIG1vZGVsLiBJIHN0b3BwZWQgYWRkaW5nIHZhcmlhYmxlcyBhcyB0aGUgQWRqdXN0ZWQgcl4yIHN0YXJ0ZWQgZHJvcHBpbmcgYW5kIG91ciBtdWx0aXBsZSByXjIgd2FzIGJhcmVseSBnb2luZyB1cC4KClNvIHdlIGNhbiBzZWUgdGhhdCB0aGUgbW9yZSByZWNlbnQgdGhlIHJlbGVhc2UsIHRoZSBtb3JlIGRhbmNlYWJpbGl0eSwgdGhlIGxvdWRlciBpdCBpcywgdGhlIGxlc3MgbGl2ZW5lc3MgaXQgaGFzLiBTbyB5b3UgZG9uJ3Qgd2FudCBhIGxpdmUgcmVjb3JkaW5nLCB5b3Ugd2FudCBhIHN0dWRpbyByZWNvcmRpbmcgd2l0aCBzb21lIGV4cGxpY2l0IGx5cmljcyBjaHVja2VkIGluIHRoZXJlIGFzIHdlbGwuCgpBbGwgb2Ygb3VyIFAtVmFsdWVzIGFyZSBzaWduaWZpY2FudCBhbmQgd2UgaGF2ZSBhIE11bHRpcGxlIHJeMiBvZiAwLjU1LCB3aXRoIGFuIGFkanVzdGVkIHJeMiBhbHNvIG9mIDAuNTUuIFRoaXMgbWVhbnMgdGhhdCA1NSUgb2YgdGhlIHZhcmlhbmNlIGluIHBvcHVsYXJpdHkgaXMgZXhwbGFpbmVkIG91ciBvdGhlciB2YXJpYWJsZXMuIFdoaWNoICBhbHNvIG1lYW5zIHRoYXQgNDUlIG9mIHRoZSB2YXJpYWJpbGl0eSBpbiB0aGUgZGF0YSBjYW5ub3QgYmUgZXhwbGFpbmVkIGJ5IHRoaXMgbW9kZWwuCgo1NSUgaXNuJ3QgYSB2ZXJ5IGhpZ2ggcHJvcG9ydGlvbiBidXQgaXQncyBub3QgdGVycmlibGUuIFdlIGFyZSB0cnlpbmcgdG8gbWVhc3VyZSB0aGUgcG9wdWxhcml0eSBvZiBhIHNvbmcuIEl0J3Mgbm90IHF1aXRlIGFzIG9idmlvdXMgYXMgaWYgd2Ugd2VyZSB0cnlpbmcgdG8gZXhwbGFpbiB0aGUgdmFsdWUgb2YgYSBob3VzZS4gV2UgbWlnaHQgZmluZCB0aGF0IHRoZSBwb3N0Y29kZSBhbmQgdGhlIG51bWJlciBvZiByb29tcyBnb2VzIGEgbG9uZyB3YXkgdG8gZXhwbGFpbmluZyB0aGF0IHZhbHVlLiBJIHRoaW5rIGV4cGxhaW5pbmcgdGhlIHBvcHVsYXJpdHkgb2YgYSBzb25nIGlzIGJpdCBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gdGhhdC4gSWYgaXQgd2FzIGVhc3kgdG8ga25vdyB3aGF0IG1hZGUgYSBzb25nIHBvcHVsYXIgdGhlbiB3ZSdkIGFsbCBiZSBtdXNpY2lhbnMuCgpNZW50aW9uIGh1bWFuIGJlaGF2aW91ciwgbWVudGlvbiB0aGUgYmFzaWMgcHJhY3RpY2Ugb2Ygc3RhdGlzdGljcyB3b3VsZCBjYWxsIHRoaXMgYSBtb2RlcmF0ZSBlZmZlY3Qgc2l6ZS4gCgoKYGBge3J9Cm1vZGVsXzZiIDwtIGxtKHBvcHVsYXJpdHkgfiB5ZWFyICsgZGFuY2VhYmlsaXR5ICsgbG91ZG5lc3MgKyBsaXZlbmVzcyArIGV4cGxpY2l0LAogICAgICAgICAgICAgICBkYXRhID0gdGVzdF9sbSkKCnN1bW1hcnkobW9kZWxfNmIpCgpgYGAgCgpTbyBteSBtb2RlbCBpc24ndCBncmVhdC4gV2hhdCBjYW4gSSBkbyB0byBpbXByb3ZlIHRoaXM/IFdlbGwuLi4KCldoZW4gSSB3YXMgcmVzZWFyY2hpbmcgaG93IHNwb3RpZnkgY2FsY3VsYXRlIHRoZWlyIHBvcHVsYXJpdHkgc2NvcmUgSSBrZXB0IGNvbWluZyBhY3Jvc3MgdGhpcyBvbmUgcGhyYXNlLgoKIyMjIDUwIGlzIHRoZSBtYWdpYyBudW1iZXIKClRoZSBoaWdoZXIgeW91ciBwb3B1bGFyaXR5IGluZGV4LCB0aGUgbW9yZSBsaWtlbHkgdGhlIGFsZ29yaXRobSBpcyB0byByZWNvbW1lbmQgeW91IHRvIG5ldyBsaXN0ZW5lcnMsIGFuZCBwbGFjZSB5b3UgaW4gYWxnb3JpdGhtaWMgcGxheWxpc3RzIGxpa2UgUmVsZWFzZSBSYWRhciBhbmQgRGlzY292ZXIgV2Vla2x5LiBNYW55IHdlYnNpdGVzIGFuZCBibG9ncyBoYWQgdGhlb3JpZXMgb24gd2hhdCBudW1iZXIgeW91IGhhZCB0byBoaXQgdG8gYmUgYWRkZWQgdG8gY2VydGFpbiBlZGl0b3JpYWwgcGxheWxpc3RzLiAKCkRJWU11c2ljaWFuIHN1Z2dlc3RzIHRoYXQgYW5kIHBvcHVsYXJpdHkgb2YgMjArIGluIHRoZSBmaXJzdCBmZXcgd2Vla3Mgb2YgcmVsZWFzZSB3aWxsIGdldCB5b3Ugb250byB0aGUgUmVsZWFzZSBSYWRhciBwbGF5bGlzdCBhbmQgYSBwb3B1bGFyaXR5IHNjb3JlIG9mIDMwKyB3aWxsIGdldCB5b3Ugb250byBEaXNjb3ZlciBXZWVrbHkuIExvdWRsYWIgc3VnZ2VzdGVkIHRoYXQgNTAgaXMgdGhlIG1hZ2ljIG51bWJlci4gSSBsaWtlZCB0aGlzIGlkZWEgb2YgaGF2aW5nIGEgdGhyZXNob2xkIG9mIHdoZXRoZXIgb3Igbm90IGEgc29uZyBpcyBwb3B1bGFyLiBTbyBnb2luZyBiYWNrIHRvIG15IHZhcmlhYmxlcyBJIGNyZWF0ZWQgYSBjb2x1bW4gY2FsbGVkIGlzX3BvcHVsYXIgd2hpY2ggaXMgb25seSBUUlVFIGlmIHRoZSBwb3B1bGFyaXR5IG9mIHRoZSBzb25nIGlzIDUwIG9yIG92ZXIuIFRoaXMgYWxzbyBsZW5kcyBpdHNlbGYgbmljZWx5IHRvIGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbC4gCgpMb2dpc3RpYyByZWdyZXNzaW9uIGlzIGEgc3RhdGlzdGljYWwgYW5hbHlzaXMgbWV0aG9kIHRvIHByZWRpY3QsIG9yIGV4cGxhaW4gYSBiaW5hcnkgb3V0Y29tZSwgc3VjaCBhcyB5ZXMgb3Igbm8sIGJhc2VkIG9uIHByaW9yIG9ic2VydmF0aW9ucyBvZiBhIGRhdGEgc2V0LgoKU28gcmF0aGVyIHRoYW4gdXNpbmcgdGhlIHBvcHVsYXJpdHkgc2NvcmUgSSBoYXZlIHVzZWQgdGhlIHZhcmlhYmxlIEkgY3JlYXRlZCBjYWxsZWQgaXNfcG9wdWxhciwgd2hpY2ggc3BsaXRzIHRoZSBkYXRhIGluIHRvIGEgbG9naWNhbCB0eXBlLCBzbyBpdCdzIFRSVUUgaWYgdGhlIHNvbmcgaXMgNTAgb3IgYWJvdmUuCgpUaGUgd2F5IHRoaXMgaXMgYnVpbHQgaXMgdmVyeSBzaW1pbGFyIHRvIHRoZSBsaW5lYXIgbW9kZWwuIEkgbG9vayBmb3IgY29ycmVsYXRpb25zLCBhbmQgSSBhZGQgdGhlbSB0byBteSBtb2RlbCAxIGF0IGEgdGltZSwgY2hlY2sgdGhleSBhcmUgc2lnbmlmaWNhbnQuIFRoZSBtYWluIGRpZmZlcmVuY2UgaXMgdGhhdCBJJ20gbG9va2luZyBmb3IgZm9yIGEgaGlnaCBBVUMgc2NvcmUgdGhpcyB0aW1lLCByYXRoZXIgdGhhbiB0aGUgbXVsdGlwbGUgcl5zcXVhcmVkIEkgd2FzIGxvb2tpbmcgZm9yIGluIHRoZSBsaW5lYXIgbW9kZWwuCgpJJ2xsIGV4cGxhaW4gdGhlIEFVQyBpbiBhIHNlY29uZC4gSSBkZWNpZGVkIGZvciB0aGlzIG1vZGVsIHRvIG1ha2UgYSBjb3VwbGUgb2YgY2hhbmdlcy4gSSBkZWNpZGVkIHRvIG5vIGxvbmdlciBpbmNsdWRlIHRoZSB5ZWFyIG9yIGRlY2FkZSB0aGUgc29uZyB3YXMgcmVsZWFzZWQuIElmIEknbSBzdGF5aW5nIHRydWUgdG8gbXkgb3JpZ2luYWwgcXVlc3Rpb24gdGhlbiBob3cgY291bGQgSSBwb3NzaWJseSB3cml0ZSBhIHNvbmcgdGhhdCB3YXMgcmVsZWFzZWQgaW4gdGhlIHBhc3QuIEl0IGhhZCBzdWNoIGEgbGFyZ2UgaW5mbHVlbmNlIG9uIHRoZSBsaW5lYXIgbW9kZWwgSSB0aG91Z2h0IGl0IHdvdWxkIGJlIG1vcmUgaW50ZXJlc3RpbmcgdG8gc2VlIGhvdyB0aGUgbG9naXN0aWMgbW9kZWwgZmFyZWQgd2l0aG91dCBpdC4gQW5kIHRoZW4gSSBjYW4gdGVzdCBteSBtb2RlbCBhZ2FpbnN0IGRpZmZlcmVudCBkZWNhZGVzIHRvIHNlZSBob3cgaXQgcGVyZm9ybXMuCgoKT3NjYXIgV2lsZGUgaXMgZmFtb3VzbHkgY3JlZGl0ZWQgd2l0aCBoYXZpbmcgd3JpdHRlbjog4oCcUG9wdWxhcml0eSBpcyB0aGUgb25lIGluc3VsdCBJIGhhdmUgbmV2ZXIgc3VmZmVyZWQu4oCdCgpgYGB7cn0Kc3BvdF9zYW1wbGUgJT4lIAogIG11dGF0ZShleHBsaWNpdCA9IGFzLmxvZ2ljYWwoZXhwbGljaXQpKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gbG91ZG5lc3MsIHkgPSBwb3B1bGFyaXR5LCBjb2xvdXIgPSBleHBsaWNpdCkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjgpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkxvdWRuZXNzIiwKICAgICAgIHkgPSAiUG9wdWxhcml0eSIsCiAgICAgICB0aXRsZSA9ICJSZWxhdGlvbnNoaXAgYmV0d2VlbiBQb3B1bGFyaXR5IGFuZCBMb3VuZGVzcyIsCiAgICAgICBzdWJ0aXRsZSA9ICJHcm91cGVkIGJ5IGV4cGxpY2l0IG9yIG5vdCIpICsKICAgIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICAiRGFyazIiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0ICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTUsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGF4aXMudGl0bGUgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNSwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTAsIGZhbWlseSA9ICJUaW1lcyIpCiAgKSAKYGBgCgoKYGBge3J9CnNwb3Rfc2FtcGxlICU+JSAKICBtdXRhdGUoZXhwbGljaXQgPSBhcy5sb2dpY2FsKGV4cGxpY2l0KSkgJT4lCmdncGxvdCgpICsKICBhZXMoeCA9IGxvdWRuZXNzLCB5ID0gYXMuaW50ZWdlcihpc19wb3B1bGFyKSwgY29sb3VyID0gZXhwbGljaXQpICsKICBnZW9tX2ppdHRlcihzaGFwZSA9IDEsCiAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAuMDUsIHcgPSAwLjA1KSwKICAgICAgICAgICAgICBhbHBoYSA9IDAuOCkgKwogICBnZW9tX2xpbmUoZGF0YSA9IHRyYWluX21vZGVsXzFfbG91ZCwgYWVzKHggPSBsb3VkbmVzcyAsIHkgPSBwcmVkKSwgY29sID0gJ3JlZCcpICsKICB5bGFiKCJQcm9iYWJpbGl0eSIpICsKICAgICAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gICJEYXJrMiIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNSwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTUsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMCwgZmFtaWx5ID0gIlRpbWVzIikKICApIAoKCiMgZ2dwbG90KG1vcnRnYWdlX2RhdGEpICsKIyAgIGdlb21faml0dGVyKGFlcyh4ID0gdHVfc2NvcmUsIHkgPSBhcy5pbnRlZ2VyKGFjY2VwdGVkKSksIHNoYXBlID0gMSwgCiMgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMC4wMykpICsgCiMgICAgZ2VvbV9saW5lKGRhdGEgPSBwcmVkaWN0X2xvZywgYWVzKHggPSB0dV9zY29yZSAsIHkgPSBwcmVkKSwgY29sID0gJ3JlZCcpICsgCiMgICB5bGFiKCJQcm9iYWJpbGl0eSIpCmBgYAoKCkZpbmFsIExvZ2lzdGljIFJlZ3Jlc3Npb24gTW9kZWwKYGBge3J9Cm1vZGVsXzRfZmluYWwgPC0gZ2xtKGlzX3BvcHVsYXIgfiBsb3VkbmVzcyArIGV4cGxpY2l0ICsgZGFuY2VhYmlsaXR5ICsgbm9fb2ZfYXJ0aXN0cywKICAgICAgICAgICAgIGZhbWlseSA9ICJiaW5vbWlhbCIsCiAgICAgICAgICAgICBkYXRhID0gdHJhaW5fbG9nX21vZCkKCnN1bW1hcnkobW9kZWxfNF9maW5hbCkKCnRpZHkobW9kZWxfNF9maW5hbCkKCnRyYWluX21vZGVsXzRfZmluYWwgPC0gdHJhaW5fbG9nX21vZCAlPiUKICBhZGRfcHJlZGljdGlvbnMobW9kZWxfNF9maW5hbCwgdHlwZSA9ICJyZXNwb25zZSIpCgpyb2Nfb2JqX21vZDQgPC0gdHJhaW5fbW9kZWxfNF9maW5hbCAlPiUKICByb2MocmVzcG9uc2UgPSBpc19wb3B1bGFyLCBwcmVkaWN0b3IgPSBwcmVkKQoKcm9jX2N1cnZlIDwtIGdncm9jKAogIGRhdGEgPSBsaXN0KAogICAgYmVzdF9tb2RlbCA9IHJvY19vYmpfbW9kNAogICksIAogIGxlZ2FjeS5heGVzID0gVFJVRSkgKwogIGNvb3JkX2ZpeGVkKCkgKyAKICB0aGVtZV9jbGFzc2ljKCkKCmF1Yyhyb2Nfb2JqX21vZDQpCmBgYAoKCmBgYHtyfQpsb2dfbW9kXzE5OTAgPC0gdHJhaW5fbG9nX21vZCAlPiUgCiAgZmlsdGVyKGRlY2FkZSA9PSAxOTkwIHwKICAgICAgICAgICBkZWNhZGUgPT0gMjAwMCB8CiAgICAgICAgICAgZGVjYWRlID09IDIwMTApCgptb2RlbF85MF8wMF8xMCA8LSBnbG0oaXNfcG9wdWxhciB+IGxvdWRuZXNzICsgZXhwbGljaXQgKyBkYW5jZWFiaWxpdHkgKyBub19vZl9hcnRpc3RzLAogICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gImJpbm9taWFsIiwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBsb2dfbW9kXzE5OTApCgpzdW1tYXJ5KG1vZGVsXzkwXzAwXzEwKQoKdGlkeShtb2RlbF85MF8wMF8xMCkKCnRyYWluX21vZGVsXzkwXzAwXzEwIDwtIGxvZ19tb2RfMTk5MCAlPiUKICBhZGRfcHJlZGljdGlvbnMobW9kZWxfOTBfMDBfMTAsIHR5cGUgPSAicmVzcG9uc2UiKQoKcm9jX29ial9tb2RfOTBfMDBfMTAgPC0gdHJhaW5fbW9kZWxfOTBfMDBfMTAgJT4lCiAgcm9jKHJlc3BvbnNlID0gaXNfcG9wdWxhciwgcHJlZGljdG9yID0gcHJlZCkKCgpyb2NfY3VydmUgPC0gZ2dyb2MoCiAgZGF0YSA9IGxpc3QoCiAgICBiZXN0X21vZGVsID0gcm9jX29ial9tb2Q0LAogICAgZGVjXzYwc183MHNfODBzID0gcm9jX29ial9tb2RfNjBfNzBfODAsCiAgICBkZWNfOTBzXzAwc18xMHMgPSByb2Nfb2JqX21vZF85MF8wMF8xMAogICksIAogIGxlZ2FjeS5heGVzID0gVFJVRSwKICBsaW5ld2lkdGggPSAyKSArCiAgY29vcmRfZml4ZWQoKSArCiAgbGFicyh4ID0gIjEgLSBTcGVjaWZpY2l0eSIsCiAgICAgICB5ID0gIlNlbnNpdGl2aXR5IikgKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICAiRGFyazIiKSArCiAgc2NhbGVfY29sb3VyX2Rpc2NyZXRlKGxhYmVscyA9IGMoIkZpbmFsIE1vZGVsIiwgIjYwcywgNzBzICYgODBzIiwgIjkwcywgMDBzICYgMTBzIikpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICAjbGVnZW5kLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgI2xlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCkKICApCgphdWMocm9jX29ial9tb2RfOTBfMDBfMTApCgpyb2NfY3VydmUKCmdnc2F2ZSgicGxvdF9pbWFnZXMvbG9nX21vZGVscy5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTIsIGhlaWdodCA9IDYpCgpgYGAKCgpgYGB7cn0KCmxvZ19tb2RfMTk5MCA8LSB0cmFpbl9sb2dfbW9kICU+JSAKICBmaWx0ZXIoZGVjYWRlID09IDE5OTAgfAogICAgICAgICAgIGRlY2FkZSA9PSAyMDAwIHwKICAgICAgICAgICBkZWNhZGUgPT0gMjAxMCkKCm1vZGVsXzkwXzAwXzEwIDwtIGdsbShpc19wb3B1bGFyIH4gbG91ZG5lc3MgKyBleHBsaWNpdCArIGRhbmNlYWJpbGl0eSArIG5vX29mX2FydGlzdHMsCiAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSAiYmlub21pYWwiLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGxvZ19tb2RfMTk5MCkKCnN1bW1hcnkobW9kZWxfOTBfMDBfMTApCgp0aWR5KG1vZGVsXzkwXzAwXzEwKQoKdHJhaW5fbW9kZWxfOTBfMDBfMTAgPC0gbG9nX21vZF8xOTkwICU+JQogIGFkZF9wcmVkaWN0aW9ucyhtb2RlbF85MF8wMF8xMCwgdHlwZSA9ICJyZXNwb25zZSIpCgpyb2Nfb2JqX21vZF85MF8wMF8xMCA8LSB0cmFpbl9tb2RlbF85MF8wMF8xMCAlPiUKICByb2MocmVzcG9uc2UgPSBpc19wb3B1bGFyLCBwcmVkaWN0b3IgPSBwcmVkKQoKCnJvY19jdXJ2ZSA8LSBnZ3JvYygKICBkYXRhID0gbGlzdCgKICAgIGJlc3RfbW9kZWwgPSByb2Nfb2JqX21vZDQKICApLCAKICBsZWdhY3kuYXhlcyA9IFRSVUUsCiAgbGluZXdpZHRoID0gMikgKwogIGNvb3JkX2ZpeGVkKCkgKwogIGxhYnMoeCA9ICIxIC0gU3BlY2lmaWNpdHkiLAogICAgICAgeSA9ICJTZW5zaXRpdml0eSIpICsKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAgIkRhcmsyIikgKwogIHNjYWxlX2NvbG91cl9kaXNjcmV0ZShsYWJlbHMgPSAiRmluYWwgTW9kZWwiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNiwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpCiAgKQoKYXVjKHJvY19vYmpfbW9kXzkwXzAwXzEwKQoKcm9jX2N1cnZlCgpnZ3NhdmUoInBsb3RfaW1hZ2VzL2xvZ19iZXN0X21vZGVsLnBuZyIsIGRwaSA9IDcyMCwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gNikKCmBgYAoKCgoK